home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************
- Copyright (C) 1990, 1991, 1993 Andy C. Hung, all rights reserved.
- PUBLIC DOMAIN LICENSE: Stanford University Portable Video Research
- Group. If you use this software, you agree to the following: This
- program package is purely experimental, and is licensed "as is".
- Permission is granted to use, modify, and distribute this program
- without charge for any purpose, provided this license/ disclaimer
- notice appears in the copies. No warranty or maintenance is given,
- either expressed or implied. In no event shall the author(s) be
- liable to you or a third party for any special, incidental,
- consequential, or other damages, arising out of the use or inability
- to use the program for any purpose (or the loss of data), even if we
- have been advised of such possibilities. Any public reference or
- advertisement of this source code should refer to it as the Portable
- Video Research Group (PVRG) code, and not by any author(s) (or
- Stanford University) name.
- *************************************************************/
- /*
- ************************************************************
- cyuv2ppm.c
-
- This program converts component YUV files with a sampling ratio of
- 4:1:1 (the same pattern as MPEG 4:2:0; the files read from .Y .U .V by
- default) into a single raw ppm file.
-
- The ppm description and files are part of Jef Poskanzer's PBMPLUS
- library. This is just a short-cut program to do a simple RGB
- conversion.
-
- -----
- Modifications by Son H. Le on 01-Sep-93
- o replaced all exit(-1) with exit(0)
- o added exit(0) after convertYUV2RGB()
- o added #include <stdlib.h> and <string.h>
- o added prototype convertYUV2RGB()
- ************************************************************
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #define PPM_MAGIC1 'P'
- #define PPM_MAGIC2 '3'
- #define RPPM_MAGIC2 '6'
- #define FIXNUM 16
-
- #define FIX(a,b) ((int)((a)*(1<<(b))))
- #define UNFIX(a,b) ((a+(1<<(b-1)))>>(b))
-
- /* Approximate 255 by 256 */
- #define ICCIRUV(x) (((x)<<8)/224)
- #define ICCIRY(x) ((((x)-16)<<8)/219)
-
- #define CLIP(t) (((t)>255)?255:(((t)<0)?0:(t)))
- #define GETR(y,u,v) UNFIX((FIX(1.0,FIXNUM)*(y)+\
- FIX(1.402,FIXNUM)*(v)),FIXNUM)
- #define GETG(y,u,v) UNFIX((FIX(1.0,FIXNUM)*(y)+\
- FIX(-0.34414,FIXNUM)*(u)+\
- FIX(-0.71414,FIXNUM)*(v)),FIXNUM)
- #define GETB(y,u,v) UNFIX((FIX(1.0,FIXNUM)*(y)+\
- FIX(1.772,FIXNUM)*(u)),FIXNUM)
- char *suffix[3] = {".Y",".U",".V"};
-
- void convertYUV2RGB(int cols,int rows,FILE *iny,FILE *inu,FILE *inv,
- FILE *out,int CCIR601);
-
- void
- convertYUV2RGB(cols, rows, iny, inu, inv, out, CCIR601)
- int cols,rows;
- FILE *iny,*inu,*inv,*out;
- int CCIR601;
- {
- int i,j;
- int y1,y2,y3,y4,u1,v1;
- int temp;
- unsigned char *temprgb1, *temprgb2, *tempy1, *tempy2, *tempu, *tempv;
- unsigned char *rgb1p, *rgb2p, *y1p, *y2p, *up, *vp;
-
- fprintf(out,"%c%c\n%d %d\n%d\n",PPM_MAGIC1,RPPM_MAGIC2,cols,rows,255);
- printf("input size: %dx%d\t output size: %dx%d\n",
- cols,rows,cols,rows);
-
- temprgb1 = (unsigned char *) calloc(cols*3,sizeof(char));
- temprgb2 = (unsigned char *) calloc(cols*3,sizeof(char));
- tempy1 = (unsigned char *) calloc(cols,sizeof(char));
- tempy2 = (unsigned char *) calloc(cols,sizeof(char));
- tempu = (unsigned char *) calloc(cols>>1,sizeof(char));
- tempv = (unsigned char *) calloc(cols>>1,sizeof(char));
-
- if ((rows&1)||(cols&1))
- {
- printf("rows and columns must be multiple of 2\n");
- exit(0);
- }
- for(i=0;i<(rows>>1);i++)
- {
- fread(tempy1,1,cols*sizeof(char),iny);
- fread(tempy2,1,cols*sizeof(char),iny);
- fread(tempu,1,(cols>>1)*sizeof(char),inu);
- fread(tempv,1,(cols>>1)*sizeof(char),inv);
-
- rgb1p = temprgb1;
- rgb2p = temprgb2;
- y1p = tempy1;
- y2p = tempy2;
- up = tempu;
- vp = tempv;
-
- for(j=0;j<(cols>>1);j++)
- { /* We use pel replication for interpolation */
- y1 = *(y1p++);
- y2 = *(y1p++);
- y3 = *(y2p++);
- y4 = *(y2p++);
-
- u1 = *(up++);
- v1 = *(vp++);
- u1 -=128;
- v1 -=128;
-
- if (CCIR601)
- {
- y1 = ICCIRY(y1);
- y2 = ICCIRY(y2);
- y3 = ICCIRY(y3);
- y4 = ICCIRY(y4);
-
- u1 = ICCIRUV(u1);
- v1 = ICCIRUV(v1);
- }
-
- temp=GETR(y1,u1,v1);
- *(rgb1p++) = CLIP(temp);
- temp=GETG(y1,u1,v1);
- *(rgb1p++) = CLIP(temp);
- temp=GETB(y1,u1,v1);
- *(rgb1p++) = CLIP(temp);
-
- temp=GETR(y2,u1,v1);
- *(rgb1p++) = CLIP(temp);
- temp=GETG(y2,u1,v1);
- *(rgb1p++) = CLIP(temp);
- temp=GETB(y2,u1,v1);
- *(rgb1p++) = CLIP(temp);
-
- temp=GETR(y3,u1,v1);
- *(rgb2p++) = CLIP(temp);
- temp=GETG(y3,u1,v1);
- *(rgb2p++) = CLIP(temp);
- temp=GETB(y3,u1,v1);
- *(rgb2p++) = CLIP(temp);
-
- temp=GETR(y4,u1,v1);
- *(rgb2p++) = CLIP(temp);
- temp=GETG(y4,u1,v1);
- *(rgb2p++) = CLIP(temp);
- temp=GETB(y4,u1,v1);
- *(rgb2p++) = CLIP(temp);
-
- }
- fwrite(temprgb1,1,cols*3*sizeof(char),out);
- fwrite(temprgb2,1,cols*3*sizeof(char),out);
- }
- }
-
- int
- main(argc, argv)
- int argc;
- char **argv;
- {
- int i;
- int CCIR601=0;
- int width=352,height=240;
- int suffixcount=0;
- char *infile,*outfile;
- char infiley[256];
- char infileu[256];
- char infilev[256];
- FILE *out,*iny,*inu,*inv;
-
- if (argc<3)
- {
- printf("cyuv2ppm infile outfile [-iw width] [-ih height] [-z suffix]* [-CCIR601]\n");
- printf("\n");
- printf("width = 352 by default, width of component input file\n");
- printf("height = 240 by default, width of component input file\n");
- printf("infile is the input yuv file; default infile.Y infile.U infile.V.\n");
- printf("outfile is the output ppm file.\n");
- printf("-z specifies alternate suffixes:\n");
- printf(" e.g. cyuv2ppm inp out.ppm -z .y -z .cb -z .cr\n");
- printf(" will input in.y, in.cb, in.cr, respectively\n");
- printf("-CCIR601 specifies CCIR601 yuv space (default JFIF).\n");
- exit(0);
- }
-
- for(i=3;i<argc;i++)
- {
- if (!strcmp(argv[i],"-z"))
- {
- if (suffixcount==3)
- {
- printf("too many suffixes\n");
- exit(0);
- }
- suffix[suffixcount++] = argv[++i];
- }
- else if (!strcmp(argv[i],"-iw"))
- width = atoi(argv[++i]);
- else if (!strcmp(argv[i],"-ih"))
- height = atoi(argv[++i]);
- else if (!strcmp(argv[i],"-CCIR601"))
- CCIR601=1;
- else
- {
- printf("unknown option: %s\n",argv[i]);
- exit(0);
- }
- }
-
- infile = argv[1];
- outfile = argv[2];
- sprintf(infiley,"%s%s",infile,suffix[0]);
- sprintf(infileu,"%s%s",infile,suffix[1]);
- sprintf(infilev,"%s%s",infile,suffix[2]);
-
- if (!(out=fopen(outfile,"w")))
- {
- printf("cannot open file: %s\n",outfile);
- exit(0);
- }
- if (!(iny=fopen(infiley,"r")))
- {
- printf("cannot open file: %s\n",infiley);
- exit(0);
- }
- if (!(inu=fopen(infileu,"r")))
- {
- printf("cannot open file: %s\n",infileu);
- exit(0);
- }
- if (!(inv=fopen(infilev,"r")))
- {
- printf("cannot open file: %s\n",infilev);
- exit(0);
- }
- convertYUV2RGB(width,height,iny,inu,inv,out,CCIR601);
- exit(0);
- }
-
-